#ifndef CORE_H
#define CORE_H

#include <set>
#include <list>
#include <iostream>
#include <SDL/SDL.h>
using namespace std;

#include "../definiciones_globales.h"
#include "FSM/FSM.h"
#include "Alarma/Alarma.h"
#include "Timer/Timer.h"
#include "Evento/Evento.h"
#include "Callback/Callback.h"
#include "Pantalla/Pantalla.h"

struct Teclas_t
{
	Evento arriba;
	Evento abajo;
	Evento derecha;
	Evento izquierda;
};

struct Teclado
{
	Teclas_t al_tocar;
	Teclas_t al_soltar;
};

/* workaround por includes circulares */
class Alarma;
class FSM;

/* TODO: Implementar una consolita de debug grafica con SDL_ttf */
// TODO: ver de eliminar el destructor. No pasa por el si la clase es un singleton global
/* TODO: Como la clase al ser un singleton global no pasa por el destructor, no llama a los destructores de las clases instanciadas 
 * Considerar llamarlos en Salir() o poner punteros y hacer delete en Salir() */
/* TODO: Ver de refactorizar el Main() que esta un poco chancho */
/* TODO: Refactorizar esto porque es un quilombo ilegible */
/* TODO: Implementar ValidadorDeMovimientos */
class Core
{
	public:
		~Core();
		void Init();
		void Salir();
		void AgregarCallback(BaseCallback* callback);
		bool EliminarCallback(BaseCallback* callback);
		void AgregarAlarma(int llamadas, int tiempo, BaseCallback* _callback);
		Teclado& Teclas();
		Pantalla_t& Pantalla();
		FSM& getFSM();
		static Core* Instancia(); // Devuelve el singleton
	protected:
		Core(int fps);
	private:
		int frame_ticks;
		set<BaseCallback*> callbacks;
		list<Alarma*> alarmas;
		Teclado teclas;
		Pantalla_t pantalla;
		FSM fsm;
		static Core* instancia; // instancia singleton
	// funciones aux
		void Main();
		void HandleKeyEvents(SDL_Event& event);
		void RevisarAlarmas();
		void DesactivarAlarmas();
};

#endif
